using System;
using System.Collections;
using Meta;

namespace Meta.Editor {
	/// <summary>
	/// Searches unintelligently for something that looks like a type declaration for targetVariable
	/// </summary>
	public class TypeGuesser : Reader {
		CodeBox code;
		Type guess;
		Symbol targetVariable;
		TypeGuesser(CodeBox code, EditorTextReader stream, Symbol targetVariable) : base(stream, stream.scanner.charIndex) {
			this.code = code;
			this.guess = null;
			this.targetVariable = targetVariable;
		}

		public static Type GuessType(CodeBox code, int start, string varName) {
			TypeGuesser g = new TypeGuesser(code, new EditorTextReader(code.ScanCharsFrom(start)), Symbol.Intern(varName));
			try {
				g.Read();
			} catch {}
			return g.guess;
		}

		ArrayList lastList;
		public override void EndElement(System.Collections.ArrayList l) {
			lastList=l;
		}

		public override void EndList() {
			if (lastList.Count>1 && lastList.Count<4 && lastList[0] is Symbol && lastList[1] is Symbol) {
				Symbol maybeType = (Symbol)lastList[0];
				Keyword k=lastList[1] as Keyword;
				object binding=code.Namespace.CheckBinding(maybeType.name);
				Type t = (binding!=null)?(binding as Type):null;

				if (t!=null && (lastList[1]==targetVariable || (k!=null && k.SymbolForm==targetVariable)))
					guess = t;
			}
		}
	}
}
